<script setup lang="ts" name="BpmnListeners">
import { mapState } from 'pinia'
import { useModelerStore } from '@/store/bpmnProcess/modelerStore'
import { isTaskListener, isExecuteListener, getListenerEventTypeObject, getListenerTypeObject, getListenerType, getListeners, addListener, removeListener, updateListener } from '../../../utils/listeners'
import EventEmitter from '@/utils/EventEmitter'
import useMessageBox from '@/hooks/useMessageBox'
import ListenersDrawer from './components/ListenersDrawer.vue'
import { cloneDeep } from 'lodash-es'

const { messageBox } = useMessageBox()

const props = defineProps({
  type: {
    type: String,
    default: ''
  }
})

const ListenersDrawerRef = ref(null)

const editIndex = ref(-1)
let listenersRaw = markRaw([])
const listeners = ref([])

const listenerEventTypeObject = ref(null)
const listenerTypeObject = ref(null)

const mapStates = computed(() => {
  return mapState(useModelerStore, ['getActive'])
})

// 新增监听器
const add = () => {
  editIndex.value = -1
  ListenersDrawerRef.value.showDrawer({ type: props.type })
}

// 编辑监听器
const edit = (row, idx) => {
  editIndex.value = idx
  ListenersDrawerRef.value.showDrawer({ type: props.type, row: row })
}

// 删除监听器
const deleteRow = (index) => {
  const msg = '确认<span>删除</span>该监听器吗？'
  const msgTips = ''
  messageBox('danger', true, msg, msgTips, () => {
    removeListener(mapStates.value.getActive(), listenersRaw[index])
  })
}

// 初始化监听器数据
const initData = () => {
  listenerTypeObject.value = getListenerTypeObject()
  listenerEventTypeObject.value = getListenerEventTypeObject()
  listenersRaw = markRaw(getListeners(mapStates.value.getActive(), props.type))
  listeners.value = cloneDeep(listenersRaw)
  listeners.value.forEach((item) => {
    item.type = getListenerType(item, props.type)
  })
}

// 监听器新增/编辑数据更新到bpmn中
const listenerChange = (v) => {
  if (editIndex.value === -1) {
    addListener(mapStates.value.getActive(), props.type, v)
  } else {
    updateListener(mapStates.value.getActive(), props.type, v, listenersRaw[editIndex.value])
  }
}

const eventEmitterListener = () => {
  if (props.type === 'ExecutionListener' && isExecuteListener(mapStates.value.getActive()) || props.type === 'TaskListener' && isTaskListener(mapStates.value.getActive())) {
    initData()
  }
}

onBeforeUnmount(() => {
  EventEmitter.removeListener('element-update', eventEmitterListener)
})

onMounted(() => {
  initData()
  EventEmitter.on('element-update', eventEmitterListener)
})
</script>

<template>
  <el-collapse-item :name="props.type">
    <template #title>
      <div class="collapse-header">
        <svg-icon v-if="props.type === 'TaskListener'" icon="ri:radar-fill"></svg-icon>
        <svg-icon v-if="props.type === 'ExecutionListener'" icon="ri:remote-control-fill"></svg-icon>
        <h2>{{ props.type === 'TaskListener' ? '任务' : '执行' }}监听器</h2>
        <el-button type="primary" size="small" plain circle>{{ listeners.length }}</el-button>
      </div>
    </template>
    <el-form-item>
      <el-table :data="listeners" border>
        <el-table-column type="index" label="序号" width="60" />
        <el-table-column prop="event" label="事件类型" :formatter="row => listenerEventTypeObject[row.event]" />
        <el-table-column v-if="props.type === 'TaskListener'" prop="id" label="监听器ID" show-overflow-tooltip />
        <el-table-column prop="type" label="监听器类型" show-overflow-tooltip :formatter="row => listenerTypeObject[row.type]" />
        <el-table-column prop="operate" label="操作" width="110" align="center">
          <template #default="scope">
            <el-button type="primary" icon="Edit" circle @click="edit(scope.row, scope.$index)"></el-button>
            <el-button type="danger" icon="Delete" circle @click="deleteRow(scope.$index)"></el-button>
          </template>
        </el-table-column>
      </el-table>
      <el-button class="add" type="primary" icon="Plus" @click="add">
        添加
        {{ props.type === 'TaskListener' ? '任务' : '执行'}}
        监听器
      </el-button>
    </el-form-item>
    <ListenersDrawer ref="ListenersDrawerRef" @save="listenerChange"></ListenersDrawer>
  </el-collapse-item>
</template>

<style scoped lang="scss">
.el-collapse-item {
  :deep(.el-collapse-item__header) {

    .collapse-header {
      display: flex;
      flex: 1;
      align-items: center;
      padding: 0 12px;

      .el-icon {
        margin-right: 6px;
        font-size: 20px !important;
      }

      h2 {
        display: flex;
        flex: 1;
        justify-content: flex-start;
        font-weight: bold;
        font-size: 14px;
      }

      .el-button {
        margin-left: 12px;
      }
    }

    .el-icon {
      font-size: 18px;
    }
  }

  :deep(.el-collapse-item__content) {
    padding-right: 12px;
    padding-bottom: 12px;
    padding-left: 12px;
  }
}

.el-form-item {
  :deep(.el-form-item__content) {
    margin-left: 0 !important;

    .el-button.add {
      width: 100%;
      margin: 12px 0 0;
    }
  }
}
</style>
